package org.shiro.utils;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.session.Session;
import org.cleaver.spring.application.ApplicationContextUtil;
import org.shiro.basic.entity.Login;
import org.shiro.basic.properties.ShiroPropriety;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Shiro相关工具类
 *
 * @author LiKun
 * @date 2021/11/3 11:30
 */
public class ShiroUtil {
    /**
     * 获取当前登录用户ID
     *
     * @return 当前登录用户ID
     */
    public static final String getUserId() {
        return SecurityUtils.getSubject().getPrincipal().toString();
    }

    /**
     * 获取当前登录用户的SessionId
     *
     * @return SessionId
     */
    public static final String getSessionId() {
        return String.valueOf(SecurityUtils.getSubject().getSession().getId());
    }

    /**
     * 获取并返回SessionKey
     *
     * @param sessionId sessionId
     *
     * @return sessionKey
     */
    public static String getSessionKey(String sessionId) {
        ShiroPropriety shiroPropriety = ApplicationContextUtil.getBean(ShiroPropriety.class);
        return shiroPropriety.getSessionPrefix().concat(sessionId).intern();
    }

    /**
     * 根据给定的登录信息获取Token数据
     *
     * @param login 登录信息
     *
     * @return Token数据
     */
    public static final UsernamePasswordToken getUserPasswordToken(Login login) {
        return new UsernamePasswordToken(login.getUsername(), login.getPassword());
    }

    /**
     * 向Shiro.Session中设置自定义数据
     *
     * @param session session
     * @param values  自定义数据
     */
    public static void putValue2Session(Session session, Map<Object, Object> values) {
        values.forEach(session::setAttribute);
    }

    public static List<Class> getRequiresAuthenticationAnnotations() {
        List<Class> annotations = new ArrayList<>(3);
        annotations.add(RequiresAuthentication.class);
        annotations.add(RequiresPermissions.class);
        annotations.add(RequiresRoles.class);
        return annotations;
    }
}
